<?php
/**
 * Author: ChenGuangHui
 * Email：13035809409@163.com
 * Date Time: 2021/7/15 17:45
 */


namespace App\Logic\Common;


use App\Exceptions\RJsonError;
use App\Logic\CommLogic;
use App\Models\Common\OperationLog;
use App\Models\Rbac\RbacMenu;
use App\Models\Rbac\RbacPublic;
use App\Models\Rbac\RbacRole;
use App\Models\Rbac\RbacUnit;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use OSS\Core\OssException;
use OSS\Core\OssUtil;
use OSS\OssClient;
use Overtrue\ChineseCalendar\Calendar;

class BaseLogic extends CommLogic
{

    /**
     * @return \App\Models\Model[]|Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Query\Builder[]|\Illuminate\Support\Collection
     */
    public function lists()
    {
        $menu = RbacMenu::query()->where('status', 1)->orderByDesc('sort')->get()->toArray();
        if (auth('api')->user()->is_liable !== 1) {
            $authCodes = RbacMenu::query()->where('status', 1)->orderByDesc('sort')->get()->toArray();
            $menuIds = array();
            foreach ($authCodes as $v) {
                if ($v['parent_id'] > 0) {
                    $menuIds[] = $this->_getNodes(collect($menu)->keyBy('id')->toArray(), $v['parent_id']);
                }
            }
            $menuIds = array_merge(array_unique(Arr::collapse($menuIds)), array_column($authCodes, 'id'));
            $menu = RbacMenu::query()->where('status', 1)->whereIn('id', $menuIds)->orderByDesc('sort')->get()->toArray();
        }
        return array(
            "path" => "/",
            "name" => "/",
            "redirect" => "/home",
            "component" => "layout/index",
            "children" => $this->_getTree($menu, 0)
        );
    }

    /**
     * @param $menus
     * @param $parentId
     * @return array
     */
    private function _getNodes($menus, $parentId)
    {
        $ids = [];
        if (isset($menus[$parentId])) {
            $ids[] = $parentId;
            if ($menus[$parentId]['parent_id'] <> 0) {
                $ids = array_merge($this->_getNodes($menus, $menus[$parentId]['parent_id']), $ids);
            }
        }
        return $ids;
    }

    /**
     * @param $menus
     * @param $parentId
     * @return array
     */
    private function _getTree($menus, $parentId)
    {
        $tree = [];
        foreach ($menus as $m) {
            if ($m['parent_id'] == $parentId) {
                $data = [
                    "path" => Arr::pull($m, 'path'),
                    "name" => Arr::pull($m, 'name'),
                    "component" => Arr::pull($m, 'component'),
                ];
                $data['meta'] = $m;
                $v = $this->_getTree($menus, $m['id']);
                if (!empty($v)) {
                    $data['children'] = $v;
                }
                $tree[] = $data;
            }
        }
        return $tree;
    }

    /**
     * @param array $where
     * @param array $pageData
     * @param array $sortData
     * @return mixed
     */
    public function log($where = [], $pageData = ['pageSize' => 20, 'pageNow' => 1], $sortData = [])
    {
        $lists = OperationLog::query()
            ->when(!empty($where['staffer_id']), function (Builder $query) use ($where) {
                $query->where('staffer_id', $where['staffer_id']);
            })
            ->when(!empty($where['log_type']), function (Builder $query) use ($where) {
                $query->where('log_type', $where['log_type']);
            })
            ->orderByDesc('created_at')
            ->paginate($pageData['pageSize'], ['*'], 'page', $pageData['pageNow'])
            ->toArray();

        return $lists;
    }

    /**
     * 阿里云OSS分片上传
     * @param $file
     * @param array $attributes
     * @return array
     * @throws RJsonError
     */
    public function upload($file, array $attributes = [])
    {
        $bucket = config('config.aliyun.bucket');
        try {
            $ossClient = new OssClient(config('config.aliyun.access_key'), config('config.aliyun.access_secret'), config('config.aliyun.endpoint'));
            $uploadId = $ossClient->initiateMultipartUpload($bucket, trim($attributes['file_path'], '/') . '/' . $attributes['original_name']);
        } catch (OssException $e) {
            throw new RJsonError('阿里云OSS配置错误！');
        }

        $pieces = $ossClient->generateMultiuploadParts(filesize($file));
        $responseUploadPart = array();
        $uploadPosition = 0;
        $isCheckMd5 = true;
        foreach ($pieces as $i => $piece) {
            $fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
            $toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
            $upOptions = array(
                $ossClient::OSS_FILE_UPLOAD => $file,
                $ossClient::OSS_PART_NUM => ($i + 1),
                $ossClient::OSS_SEEK_TO => $fromPos,
                $ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
                $ossClient::OSS_CHECK_MD5 => $isCheckMd5,
            );
            if ($isCheckMd5) {
                $contentMd5 = OssUtil::getMd5SumForFile($file, $fromPos, $toPos);
                $upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
            }

            try {
                $responseUploadPart[] = $ossClient->uploadPart($bucket, trim($attributes['file_path'], '/') . '/' . $attributes['original_name'], $uploadId, $upOptions);
            } catch (OssException $e) {
                throw new RJsonError($e->getMessage());
            }
        }
        $uploadParts = array();
        foreach ($responseUploadPart as $i => $eTag) {
            $uploadParts[] = array(
                'PartNumber' => ($i + 1),
                'ETag' => $eTag,
            );
        }
        try {
            $ossClient->completeMultipartUpload($bucket, trim($attributes['file_path'], '/') . '/' . $attributes['original_name'], $uploadId, $uploadParts);
        } catch (OssException $e) {
            throw new RJsonError($e->getMessage());
        }

        return array(
            'file_name' => $attributes['original_name'],
            'file_size' => filesize($file),
            'file_path' => $attributes['file_path'],
            'file_type' => $attributes['extension'],
            'original_name' => $attributes['original_name'],
            'hash' => hash_file('md5', $file),
            'file_url' => 'https://img.easyshop.org.cn/' . trim($attributes['file_path'], '/') . '/' . $attributes['original_name']
        );
    }
}
